package net.xo68.destiny.starter.manager.worker.route;

import lombok.extern.slf4j.Slf4j;
import net.xo68.destiny.contract.domain.sched.WorkerRouteStrategy;
import net.xo68.destiny.contract.enums.WorkerRouteStrategyEnum;
import net.xo68.destiny.starter.common.context.LocaleMessage;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 工作节点负载均衡路由策略管理者
 * @author wuxie
 * @version 2020-12-21
 */
@Slf4j
@Component
public class WorkerRouteStrategyManager implements SmartInitializingSingleton, ApplicationContextAware {

    private static ApplicationContext applicationContext=null;

    private static final String MESSAGE_PREFIX="worker.route.";

    private final Map<String,String> routeStrategyBeanMap= new HashMap<>();
    private final List<WorkerRouteStrategy> routeStrategyList= new LinkedList<>();

    @Autowired
    private LocaleMessage localeMessage;
    @Autowired(required = false)
    private WorkerRouteStrategyConfigurer workerRouteStrategyConfigurer;



    @Override
    public void afterSingletonsInstantiated() {
        for(WorkerRouteStrategyEnum strategyEnum : WorkerRouteStrategyEnum.values()){
            routeStrategyBeanMap.put(strategyEnum.name(),strategyEnum.getBeanName());
        }
        if(workerRouteStrategyConfigurer!=null){
            workerRouteStrategyConfigurer.configure(routeStrategyBeanMap);
        }
        log.debug("{}",routeStrategyBeanMap);
        routeStrategyBeanMap.forEach((k,v)->{
            routeStrategyList.add(new WorkerRouteStrategy(k,localeMessage.getMessage(MESSAGE_PREFIX+k.toLowerCase())));
        });
        log.debug("{}",routeStrategyList);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        WorkerRouteStrategyManager.applicationContext=applicationContext;
    }

    /**
     * 获得路由策略的实现实例
     * @param workerRouteStrategyEnum
     * @return
     */
    public IWorkerRouteStrategy getWorkerRouteStrategy(WorkerRouteStrategyEnum workerRouteStrategyEnum){
        return getWorkerRouteStrategy(workerRouteStrategyEnum.name());
    }

    /**
     * 获得路由策略的实现实例
     * @param workerRouteStrategyName
     * @return
     */
    public IWorkerRouteStrategy getWorkerRouteStrategy(String workerRouteStrategyName){
        if(!routeStrategyBeanMap.containsKey(workerRouteStrategyName)){
            return null;
        }
        return applicationContext.getBean(routeStrategyBeanMap.get(workerRouteStrategyName),IWorkerRouteStrategy.class);
    }
}
